#ifndef FRM_STRUCT_DEF_H
#define FRM_STRUCT_DEF_H
#include <stdint.h>
#include "common_typedef.h"

#ifndef PKG_DATA_OFFSET
#define PKG_DATA_OFFSET 16
#endif

#ifndef FRMHEAD_LEN_MAX
#define FRMHEAD_LEN_MAX 8
#endif

// 帧ID枚举
typedef enum pkgType
{
    INVALID,
    DEV_PING = 1, // 1：PING帧
    DEV_PONG = 2, // 2：PONG帧
    DEV_ACK = 3, // 3：设备ACK
    DEV_RST = 4, // 4：复位帧
    RESERVED5 = 5, // 5：暂时弃用
    DATA_TRANS = 6, // 8：数据传送帧
    PARA_TRANS = 7, // 7：参数传送帧
    /* 1 ~ 7号通用帧定长为2080字节 */
    REDUCED_CTRL = 8, // 8：精简控制帧（MCPS设备）
    RESERVED9 = 9, // 9：暂时弃用
    ADC_READMULTI = 10, // 10：读取多路ADC（MCPS设备）
    ADC_ECHOMULTI = 11, // 11：回报多路ADC（MCPS设备）
    CONFIG_FAILSAFE = 13, // 11：回报多路ADC（MCPS设备）
    /* 保留帧类型 */
    KZ_PING = 128, // 通用内存传输帧 mst -> slv
    KZ_PONG = 129, // 通用内存传输帧 slc -> mst
    ADC_CALIB,  // ADC校准参数下发帧
    ADC_REPORT, // ADC状态回报
    READ_RSSI,  // 读取射频模块状态
    SET_CHANNEL, // 设置射频模块信道
    MST_CONNECT, // 上位机连接
    MST_DISCONNECT, // 上位机断开连接
    MST_READDUMP, // 上位机请求设备DUMP
    DEV_DUMP, // 设备返回DUMP

    FRM_TYPE_MAX
} pkgType;

typedef enum
{
    CIO_RDY,
    CIO_PROCING, // 将缓存数据注册到任务回调
    CIO_OVF, // 队列溢出
} CioSta;

// 标准帧结构定义
typedef struct pkg
{
    char head[8];
    pkgType type;
    uint32_t dataLen;
    const uint8_t* data;
    uint32_t rcc;
} pkg;

// 3：设备ACK
typedef struct {
    uint32_t	isArmed; // 传输启停标志，1=正在传输DAC数据，2=未在传输数据
    uint32_t	pwrState; // 上下电标志，1=模组上电，0=模组断电
    uint32_t	workMode; // 工作模式，1=循环输出数据，2=不循环，数据只输出一次，其他=忽略
    uint32_t	uid[4]; // uint32，当前主控UUID
    char			verInfo[24]; // 字符串，标识固件版本信息
    uint32_t  devType; // 设备类型
    uint16_t  slotState[4][2]; // 单板状态
    uint32_t  voltClamp;
    uint8_t		reserved[20];
} AckDevInfo;

#define ACK_DATA_LEN 100
// 3：设备ACK
typedef struct {
    uint32_t 	errCode; // 收到的帧返回的错误码
    uint32_t	recvCmdID; // 收到的帧的帧属性
    uint32_t res; // 保留
    uint8_t data[ACK_DATA_LEN]; // 数据体
} FrmDevAck;

// 6：数据传送帧
#define CHANNEL_CNT_128 128
#define FRM_CH_CNT_8 8
typedef struct {
    uint32_t	dataAddr;
    uint16_t	frame[FRM_CH_CNT_8][CHANNEL_CNT_128];
    uint8_t		reserved[12];
} FrmDataTransmit;

// 7：参数传输帧
typedef struct {
    uint32_t isArmed; // 1=开启传输，2=停止传输
    uint32_t refreshRate; // 单位Hz，0-100K
    uint32_t refreshBegin; // 刷新起点
    uint32_t refreshCount; // 刷新次数
    uint32_t refreshEnd; // 刷新终点
    uint32_t isLoop; // 是否无限循环，1=循环，2=不循环，其他=忽略
    uint32_t isPwrOn; // 是否上下电，1=上电，0=断电
    uint8_t	 reserved[36];
} FrmConfigTransmit;

//  ADC校准参数下发帧
#define ADC_CALIBPTS_MAX 8
#define ADC_CHANNEL_CURR 0
#define ADC_CHANNEL_VOLT 1
#define ADC_VAL_SCALE 0.01
typedef struct FrmAdcCalib
{
    uint32_t channel;
    dataPt pts[ADC_CALIBPTS_MAX];
    uint8_t res[16];
} FrmAdcCalib;

// ADC状态回报帧
typedef struct FrmAdcReport
{
    uint32_t channel;
    uint32_t rawVal;                  // ADC转换值
    int32_t result;                  // 数码管展示值，按照0.01定点化
} FrmAdcReport;

// 读取多路ADC（MCPS）
typedef struct
{
    uint8_t	 reserved[16];
} FrmAdcReadMulti;

// 回报多路ADC（MCPS）
#define ADC_READMULTI_LEN 32
#define ADC_READMULTI_CH 2
typedef struct
{
    uint32_t adc[ADC_READMULTI_CH][ADC_READMULTI_LEN];
    uint8_t res[40];
} FrmAdcEchoMulti;

// 精简控制帧（MCPS）
typedef struct
{
    uint32_t isArmed;
    uint32_t isPwrOn;
    uint32_t isLoop;
    uint16_t data[128];
    uint8_t	 reserved[12];
} FrmReducedCmd;

// PING帧
typedef struct
{
    uint8_t	 reserved[12];
} FrmPing;

// PONG帧
typedef struct
{
    uint32_t UUID[4];
    uint32_t devID;
    uint16_t slotID[4];
    uint8_t	 reserved[4];
} FrmPong;

// 安全参数设置帧
typedef struct
{
    uint8_t res1[4];
    uint32_t voltClamp;
    uint8_t	 res2[24];
} FrmConfgiFailSafe;

// Dump 设备类型: DEVTYPE_MEASURE
typedef struct
{
    FrmPong id;
    FrmAdcCalib caliber[2];
    FrmAdcReport state[2];
} FrmDumpMeasure;
#endif
